/******************************************************************************
 * Copyright (C) 2015  671643387@qq.com
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *****************************************************************************/

#ifndef NODE_FS_FILESYSTEM_H_
#define NODE_FS_FILESYSTEM_H_

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif

#include <boost/function.hpp>
#include "node/macros.h"
#include "node/sys/thread_pool.h"

namespace node {
    namespace fs {
        class File;
        typedef ::boost::function<void(::node::fs::File *)> FileOpenAsyncHandler;
        typedef ::boost::function<void(::node::fs::File *, int)> FileReadAsyncHandler;
        typedef ::boost::function<void(::node::fs::File *, int)> FileWriteAsyncHandler;

        class FileSystem
        {
        public:
            struct Config
            {
                int background_task_worker_num;
            };
            enum State
            {
                INITIALIZED,
                UNINITIALIZED,
            };

            FileSystem(void);
            ~FileSystem(void);

            bool Initialize(struct Config &config);
            void Uninitialize(void);

            static FileSystem *instance(void) {
                return instance_;
            }

            bool OpenFileAsync(const char *filename, int openmode, int flags, FileOpenAsyncHandler callback);
            bool ReadFileAsync(::node::fs::File *file, char *buffer, int size, FileReadAsyncHandler callback);
            bool WriteFileAsync(::node::fs::File *file, const char *buffer, int size, FileWriteAsyncHandler callback);

            bool ReadFileAsync(const char *filename, char *buffer, int size, FileReadAsyncHandler callback);

        private:
            void ReadFileFunction(::node::fs::File *file, char *buffer, int size, FileReadAsyncHandler callback);
            void WriteFileFunction(::node::fs::File *file, const char *buffer, int size, FileWriteAsyncHandler callback);

            void ReadFileFunctionByName(const char *filename, char *buffer, int size, FileReadAsyncHandler callback);

            State state_;
            struct Config config_;
            ::node::sys::ThreadPool background_task_pool_;

            static FileSystem *instance_;
            DISALLOW_COPY_AND_ASSIGN(FileSystem);
        };

    }
}

#define __NODE_FS   (::node::fs::FileSystem::instance())

#endif // NODE_FS_FILESYSTEM_H_
